﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace ApiDoc
{
    /// <summary>
    /// Api Documentation for a Parameter.
    /// </summary>
    public class ParameterDocumentation : IMemberDocumentation
    {
        internal ParameterDocumentation(ParameterInfo member, ApiDocumentationManager manager)
        {
            Manager = manager;
            Member = member;
        }

        /// <summary>
        /// Gets the cref for the member.
        /// </summary>
        public string CRef
        {
            get
            {
                if (m_cref == null) {
                    // Generate the cref directly.
                    m_cref = ApiDoc.CRef.ReflectionCRefGenerator.NoPrefix.GetCRef(Member.Member)
                        + "." + Member.Name;
                }

                return m_cref;
            }
        }

        private string m_cref;

        /// <summary>
        /// Returns the member.
        /// </summary>
        protected internal ParameterInfo Member { get; protected set; }

        /// <summary>
        /// Returns the member.
        /// </summary>
        protected ApiDocumentationManager Manager { get; set; }

        /// <summary>
        /// IL Name of the type as returned by reflection.
        /// </summary>
        public string ILName
        {
            get { return Member.Name; }
        }

        public string Name
        {
            get
            {
                return Manager.CodeSyntaxGenerator.GenerateName(Member);
            }
        }

        public string CodeDefinition
        {
            get
            {
                return Manager.CodeSyntaxGenerator.GenerateCodeDefinition(Member);
            }
        }

        /// <summary>
        /// Gets the parameter type documentation this member is contained within.
        /// </summary>
        public TypeDocumentation ParameterType
        {
            get
            {
                if (m_parameterType == null) {
                    m_parameterType = Manager.GetTypeDocumentation(Member.ParameterType);
                }

                return m_parameterType;
            }
        }

        private TypeDocumentation m_parameterType;

        /// <summary>
        /// Gets the method this parameter belongs to.
        /// </summary>
        public MethodDocumentation Method
        {
            get
            {
                if (m_method == null) {
                    m_method = Manager.GetMethodDocumentation((MethodInfo)Member.Member);
                }

                return m_method;
            }
        }

        private MethodDocumentation m_method;

        /// <summary>
        /// Gets the description from the XML documentation.
        /// </summary>
        public string Description
        {
            get
            {
                var element = Manager.GetXmlDocumentation(Member);
                if (element == null) {
                    // TODO have an option that causes us to look up overriden methods or namespace methods for documentation.
                    return String.Empty;
                }

                return element.Value;
            }
        }
    }
}
